#ifndef TYPES_H
#define TYPES_H

#ifndef NULL
#define NULL ((void *)0)
#endif

#define __always_inline inline __attribute__((always_inline))
#define __noinline __attribute__((noinline))
#define __noreturn __attribute__((noreturn))

typedef _Bool bool;
enum { false, true };

typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
/**
 * @intptr_t 使用32位数值表示指针地址
 * @uintprt_t 使用无符号32数值表示地址的数值
 */
typedef int32_t intptr_t;
typedef uint32_t uintprt_t;

/**
 * @size_t 用于表示内存大小
 * @ppn_t 用于页码大小
 */
typedef uint32_t size_t;
typedef uint32_t ppn_t;

// ssize_t is a signed version of ssize_t, used in case there might be an
// error return.
typedef int32_t ssize_t;

// off_t is used for file offsets and lengths.
typedef int32_t off_t;

// Efficient min and max operations
#define MIN(_a, _b)						\
({								\
	typeof(_a) __a = (_a);					\
	typeof(_b) __b = (_b);					\
	__a <= __b ? __a : __b;					\
})
#define MAX(_a, _b)						\
({								\
	typeof(_a) __a = (_a);					\
	typeof(_b) __b = (_b);					\
	__a >= __b ? __a : __b;					\
})


/**
 * 舍取运算（当n为2的指数幂是有效）
 * 向下舍取到最接近n的倍数
 */
#define ROUNDDOWN(a,n) ({           \
    size_t __a = (size_t)(a);       \
    (typeof(a))(__a - __a % (n));   \
})
/**
 *  向上舍取到最接近n的倍数
 * 
 */
#define ROUNDUP(a,n) ({                                 \
    size_t __n = (size_t)(n);                           \
    (typeof(a))(ROUNDDOWN((size_t)(a) + __n - 1,__n));  \
})
/**
 * 返回'member'相对于结构类型开头的偏移量 
 * offsetof用于求出type类型数据结构中成员 member的偏移量（相对于首地址的偏移量），主要用到编译器的特性，将零地址强制转化成type类型。
 * offsetof = type.member − typebase = type.member − 0 = type.member
 */
#define offsetof(type, member)                                      \
((size_t)(&((type *)0)->member))

/**
 * to_struct用于将ptr转化为type类型指针。
 * 通过offsetof宏可以计算出结构体中一个成员距离首地址的距离d
 * 反过来，知道这个结构体成员的地址ptr以及距离d，可以计算出首地址。
 * typebase = type.member − offsetof = ptr − d
 * ---------实例----------
 *  struct myType{
 *      int data;
 *      list_entry_t list_entry;
 *  };
 * list_entry_t* it = le;
 *   while((it=list_next(it)) != le){
 *   	// 利用le2myType宏，将list_entry_t类型指针转化为struct myType类型指针
 *       struct myType *p = to_struct(it, struct myType, list_entry);
 *       std::cout << p->data << " ";
 *   }
 * 
 * @ptr 类型指针
 * @type struct类型
 * @mumber 成员在struct中的昵称，如上面的myType中的list_entry
 */
#define to_struct(ptr, type, member)                               \
    ((type *)((char *)(ptr) - offsetof(type, member)))

#endif
